<template>
  <div class="container">
    <h1>考试防作弊视频录制与上传</h1>
    <div class="video-container">
      <div class="video-box">
        <h2>摄像头预览</h2>
        <video ref="cameraPreview" autoplay muted></video>
      </div>
      <div class="video-box">
        <h2>屏幕预览</h2>
        <video ref="screenPreview" autoplay muted></video>
      </div>
    </div>
    <div class="controls">
      <el-button @click="startCamera" :disabled="!!cameraStream || uploading">开启摄像头</el-button>
      <el-button @click="startScreen" :disabled="!!screenStream || uploading">开启屏幕录制</el-button>
      <el-button
        type="primary"
        @click="stopRecording"
        :disabled="!cameraStream || !screenStream || uploading"
      >停止录制并上传</el-button>
    </div>
    <div v-if="uploading" class="uploading-tip">正在上传视频，请勿关闭页面...</div>
    <div v-if="cameraUploaded && screenUploaded" class="success-tip">
      视频上传成功！
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue'
import { ElMessage } from 'element-plus'

const cameraStream = ref(null)
const screenStream = ref(null)
const cameraRecorder = ref(null)
const screenRecorder = ref(null)
const cameraChunks = ref([])
const screenChunks = ref([])
const cameraPreview = ref(null)
const screenPreview = ref(null)
const uploading = ref(false)
const cameraUploaded = ref(false)
const screenUploaded = ref(false)

async function startCamera() {
  try {
    cameraStream.value = await navigator.mediaDevices.getUserMedia({ video: true, audio: true })
    cameraPreview.value.srcObject = cameraStream.value
    cameraRecorder.value = new MediaRecorder(cameraStream.value)
    cameraChunks.value = []
    cameraRecorder.value.ondataavailable = e => cameraChunks.value.push(e.data)
    cameraRecorder.value.start()
    ElMessage.success('摄像头已开启')
  } catch (err) {
    ElMessage.error('无法访问摄像头')
  }
}

async function startScreen() {
  try {
    screenStream.value = await navigator.mediaDevices.getDisplayMedia({ video: true })
    screenPreview.value.srcObject = screenStream.value
    screenRecorder.value = new MediaRecorder(screenStream.value)
    screenChunks.value = []
    screenRecorder.value.ondataavailable = e => screenChunks.value.push(e.data)
    screenRecorder.value.start()
    ElMessage.success('屏幕录制已开启')
  } catch (err) {
    ElMessage.error('无法访问屏幕')
  }
}

async function stopRecording() {
  if (uploading.value) return
  uploading.value = true
  cameraUploaded.value = false
  screenUploaded.value = false

  cameraRecorder.value.stop()
  screenRecorder.value.stop()
  cameraStream.value.getTracks().forEach(t => t.stop())
  screenStream.value.getTracks().forEach(t => t.stop())

  cameraRecorder.value.onstop = async () => {
    const blob = new Blob(cameraChunks.value, { type: 'video/webm' })
    await uploadVideo('camera', blob)
    cameraUploaded.value = true
    if (screenUploaded.value) finishUpload()
  }
  screenRecorder.value.onstop = async () => {
    const blob = new Blob(screenChunks.value, { type: 'video/webm' })
    await uploadVideo('screen', blob)
    screenUploaded.value = true
    if (cameraUploaded.value) finishUpload()
  }
}

async function uploadVideo(type, file) {
  const formData = new FormData()
  formData.append('video', file, `${type}_recording.webm`)
  try {
    const url = `http://localhost:1011/api/upload/${type}`
    const resp = await fetch(url, { method: 'POST', body: formData })
    const text = await resp.text()
    if (!resp.ok) throw new Error(text)
    ElMessage.success(`${type === 'camera' ? '摄像头' : '屏幕'}视频上传成功`)
  } catch (e) {
    ElMessage.error(`${type === 'camera' ? '摄像头' : '屏幕'}视频上传失败`)
  }
}

function finishUpload() {
  uploading.value = false
}
</script>

<style scoped>
.container {
  max-width: 900px;
  margin: 40px auto;
  padding: 20px;
  background: #fff;
  border-radius: 12px;
  box-shadow: 0 2px 16px 0 rgba(0,0,0,0.06);
}
h1 {
  text-align: center;
  margin-bottom: 30px;
}
.video-container {
  display: flex;
  justify-content: space-between;
  margin-bottom: 20px;
}
.video-box {
  width: 48%;
}
video {
  width: 100%;
  background: #000;
  border-radius: 8px;
  margin-bottom: 10px;
}
.controls {
  text-align: center;
  margin: 20px 0;
}
.uploading-tip {
  text-align: center;
  color: #32C5FF;
  margin-top: 12px;
}
.success-tip {
  text-align: center;
  color: #67c23a;
  margin-top: 16px;
  font-size: 18px;
  font-weight: bold;
}
</style> 